package engine

import (
	"log"
)

type ConcurrenceEngine struct {
	Scheduler   Scheduler
	WorkerCount int
	SaverChan   chan interface{}
}

// Initial Engine的初始化
func (ce *ConcurrenceEngine) Initial(reqs ...CrawlerRequest) {
	//开启多个go worker 处理 CrawlerRequest
	//parserResult := worker(req)
	in := make(chan CrawlerRequest)
	out := make(chan ParserResult)

	//创建Request通道
	ce.Scheduler.CreateChanRequest(in)
	for i := 0; i < ce.WorkerCount; i++ {
		go workerTask(in, out)
	}

	// 处理现有请求
	for _, req := range reqs {
		ce.Scheduler.SubmitReq(req)
	}

	//接收worker 输出的结果 out
	for {
		result := <-out

		//1、处理ITEM
		for _, item := range result.Item {
			ce.SaverChan <- item
		}

		//2、request再给Scheduler
		for _, request := range result.Request {
			ce.Scheduler.SubmitReq(request)
		}

	}
}

func workerTask(in chan CrawlerRequest, out chan ParserResult) {
	//就是之前的worker 只不过现在需要接收channel中的请求和输出channel结果
	for {
		//必须有一个空闲的worker等待 这个request 才能发送给channel request通道 才成功
		//不然以下代码会循环等待
		result := <-in
		content, err := result.HttpFunc.Request(result.ReqData)
		if err != nil {
			log.Println(err) //不停止
		}
		parserResult := result.Parser(content, result.ReqData)
		out <- parserResult
	}
}
